<?php
add_filter( 'dpa_filter_achievement_text', 'wp_filter_kses', 1 );
add_filter( 'dpa_filter_achievement_text', 'wptexturize' );
add_filter( 'dpa_filter_achievement_text', 'convert_chars' );
add_filter( 'dpa_filter_achievement_text', 'stripslashes_deep' );

function dpa_get_ea( $what, $where=array(), $limit=0, $sort='', $debug=false ) {
	global $wpdb, $bp;
	
	$where_str = " WHERE ";
	$limit_str = '';
	$table_str = '';
	$sort_str  = '';
	$multple = false;
	$use_col = false;
	$use_var = false;
	$use_row = false;

	foreach ( $where as $argument ) {

		if ( $multiple )
			$where_str .= ' AND ';

		$multiple = true;
		$type  = $argument['type'];
		$key   = $argument['key'];
		$value = $argument['value'];

		if ( $key == 'short_name') {

			$table_str = ", {$bp->dp_achievements->table_name}";
			$sql = "{$bp->dp_achievements->table_name_earnt}.achievement_id = {$bp->dp_achievements->table_name}.id";			

			if ( !empty( $value ) ) {
			 	$sql .= " AND {$bp->dp_achievements->table_name}.short_name = %{$type}";
				$where_str .= $wpdb->prepare( $sql, $value );
			} else {
				$where_str .= $wpdb->prepare( $sql );
			}
		} else {
			$where_str .= $wpdb->prepare( "{$key} = %{$type}", $value );			
		}
	}

	if ( $where_str == " WHERE " )
		$where_str = '';

	if ( $limit > 0 )
		$limit_str = " LIMIT {$limit}";

	if ( 1 == $limit ) {
		$use_col = false;
		$use_var = false;
		$use_row = true;
	}

	if ( false === strpos( $what, ',' ) && false === strpos( $what, '*' ) ) {
		$use_col = true;
		$use_var = false;
		$use_row = false;
	}

	if ( false !== strpos( $what, 'COUNT' ) || ( 1 == $limit && false === strpos( $what, ',' ) && false === strpos( $what, '*' ) ) ) {
		$use_col = false;
		$use_var = true;
		$use_row = false;
	}
	
	if ( $sort != '' )
		$sort_str = " ORDER BY {$sort}";
		
	$query = "SELECT {$what} FROM {$bp->dp_achievements->table_name_earnt}{$table_str}" . $where_str . $sort_str . $limit_str;
	
	if ( $debug )
		die( $query );

	if ( $use_col ) {
		return $wpdb->get_col( $query );
	} else if ( $use_var ) {
		return $wpdb->get_var( $query );
	} else if ( $use_row ) {
		return $wpdb->get_row( $query, 'ARRAY_A' );
	} else {
		return $wpdb->get_results( $query, 'ARRAY_A' );		
	}	
}

function dpa_get( $what, $where=array(), $limit=0, $debug=false ) {
	global $wpdb, $bp;
	
	$where_str = " WHERE ";
	$limit_str = '';
	$multple = false;
	$use_col = false;
	$use_var = false;
	$use_row = false;

	foreach ( $where as $argument ) {

		if ( $multiple )
			$where_str .= ' AND ';

		$multiple = true;
		$type  = $argument['type'];
		$key   = $argument['key'];
		$value = $argument['value'];
		$where_str .= $wpdb->prepare( "{$key} = %{$type}", $value );
	}
	
	if ( $where_str == " WHERE " )
		$where_str = '';

	if ( $limit > 0 )
		$limit_str = " LIMIT {$limit}";

	if ( 1 == $limit ) {
		$use_col = false;
		$use_var = false;
		$use_row = true;
	}

	if ( false === strpos( $what, ',' ) && false === strpos( $what, '*' ) ) {
		$use_col = true;
		$use_var = false;
		$use_row = false;
	}

	if ( false !== strpos( $what, 'COUNT' ) || ( 1 == $limit && false === strpos( $what, ',' ) && false === strpos( $what, '*' ) ) ) {
		$use_col = false;
		$use_var = true;
		$use_row = false;
	}
	
	$query = "SELECT {$what} FROM {$bp->dp_achievements->table_name}" . $where_str . $limit_str;

	if ( $debug )
		die( $query );

	if ( $use_col ) {
		return $wpdb->get_col( $query );
	} else if ( $use_var ) {
		return $wpdb->get_var( $query );
	} else if ( $use_row ) {
		return $wpdb->get_row( $query, 'ARRAY_A' );
	} else {
		return $wpdb->get_results( $query, 'ARRAY_A' );		
	}
}

//TOOD: refactor this
function dpa_count_of_ea( $user_id, $category='' ) {
	global $wpdb, $bp;
	
	if ( '' != $category ) {
		return dpa_get_ea( 'COUNT(short_name)', array( array( 'type' => 'd', 'key' => 'user_id', 'value' => $user_id ), array( 'type' => 's', 'key' => 'short_name', 'value' => '' ), array( 'type' => 's', 'key' => 'category', 'value' => $category ) ) );		
	} else {
		return dpa_get_ea( 'COUNT(id)', array( array( 'type' => 'd', 'key' => 'user_id', 'value' => $user_id ) ) );
	}
}

function dpa_has_user_earnt_any_achievements( $user_id ) {
	return ( dpa_count_of_ea( $user_id ) > 0 );
}

function dpa_get_ea_details( $user_id, $achievement_name ) {
	global $wpdb, $bp;

	return dpa_get_ea( '*', array( array( 'type' => 'd', 'key' => 'user_id', 'value' => $user_id ), array( 'type' => 's', 'key' => 'short_name', 'value' => $achievement_name ) ), 1 );
}

//TODO: refactor this
function dpa_get_list_of_ea_shortnames( $user_id, $limit=1000, $category='' ) {
	global $wpdb, $bp;

	if ( '' != $category ) {
		return dpa_get_ea( 'short_name', array( array( 'type' => 'd', 'key' => 'user_id', 'value' => $user_id ), array( 'type' => 's', 'key' => 'short_name', 'value' => '' ), array( 'type' => 's', 'key' => 'category', 'value' => $category ) ), $limit, 'achieved_at DESC' );  // special case		
	} else {
		return dpa_get_ea( 'short_name', array( array( 'type' => 'd', 'key' => 'user_id', 'value' => $user_id ), array( 'type' => 's', 'key' => 'short_name', 'value' => '' ) ), $limit, 'achieved_at DESC' );  // special case
	}
}

function dpa_update_usermeta( $user_id, $points=0 ) {
	global $wpdb, $bp;

	update_usermeta( $user_id, 'dpa_points', get_usermeta(  $user_id, 'dpa_points' ) + $points );
}

class dpa_achievement {
	var $user_id;       // user id
	var $name;          // achievement identifier
  var $max_ranks;     // number of ranks
	var $current_rank;  // current rank
	var $points;				// points rewarded
	var $counter;       // counter (used to count things)
	
	function dpa_achievement( $args ) {
		$this->_populate( $args );
	}


	/**
	 * Protected functions
	 */
	function _populate( $args ) {
		extract( $args );

		// required
		$this->user_id      = $user_id;
		$this->name         = $name;
		$this->max_ranks    = 1;
		$this->current_rank = $this->_get_current_rank();
		$this->points       = get_usermeta( $this->user_id, 'dpa_points' );
		$this->counter      = $this->_get_counter();
	}
	
	/* DJPAUL: Removed but retained max rank code/DB structure in case I decide to use it in the future .*/
	/*function _get_max_rank() {
		global $wpdb, $bp;
		
		$result = dpa_get_achievement_details( $this->name );
		if ( !$result )
			return null;

		return $result->ranks;
	}*/
	
	function _get_counter() {
		$result = get_usermeta( $this->user_id, 'dpa_' . $this->name . '_counter' );
		if ( empty( $result ) )
			$result = 0;
		
		return $result;
	}
	
	function _get_current_rank() {
		global $wpdb, $bp;
		
		$result = dpa_get_ea_details( $this->user_id, $this->name );
		if ( !$result )
			return 0;

		return $result->rank;
	}
	

	/**
	 * Public functions
	 */
	function award_achievement( $send_notification = true ) {
		do_action( 'dpa_award_achievement', $this->name, $this->points );	
		$this->increment_rank();	

		if ( $send_notification ) {
		  do_action( 'dpa_award_achievement_notification', $this->name, $this->points );
			// TODO: bp_core_add_notification & bp_example_record_activity here.
    }

		dpa_update_usermeta( $this->user_id, $this->points );
	}

	function is_already_earnt() {
		return ( $this->current_rank == $this->max_ranks );
	}

	function increment_rank( $new_rank = 1 ) {
		global $wpdb, $bp;

		//update
		if ( $this->current_rank > 0 ) {
			/*$new_rank += $this->current_rank;
			$data   = array( 'rank' => $new_rank, 'achieved_at' => current_time( 'mysql' ) );
			$where  = array( 'achievement_short_name' => $this->name, 'user_id' => $this->user_id );
			$result = $wpdb->update( $bp->dp_achievements->table_name_earnt, $data, $where );*/
			
		//insert
		} else {

			$achievement_id = dpa_get( 'id', array( array( 'type' => 's', 'key' => 'short_name', 'value' => $this->name ) ), 1 );
			$data = array( 'achievement_id' => $achievement_id, 'user_id' => $this->user_id, 'rank' => $new_rank, 'achieved_at' => current_time( 'mysql' ) );
			$result = $wpdb->insert( $bp->dp_achievements->table_name_earnt, $data );
		}
	}

	function increment_counter( $i = 1 ) {
		$this->counter += $i;
		return update_usermeta( $this->user_id, 'dpa_' . $this->name . '_counter',  $this->counter ); 
	}
}
?>